﻿using D.IdentityDbStore.DbContext;
using D.IdentityDbStore.Entities;
using D.IdentityDbStore.Mappers;
using IdentityServer4.Stores;
using SqlSugar;

namespace D.IdentityDbStore.Stores
{
    /// <summary>
    /// 重写资源存储方法
    /// </summary>
    public class ResourceStore : IResourceStore
    {

        private readonly ISqlSugarClient _db;
        public ResourceStore(DbSql dbSql)
        {
            _db = dbSql.Db;
        }


        /// <summary>
        /// 根据api名称获取相关信息
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public async Task<IdentityServer4.Models.ApiResource> FindApiResourceAsync(string name)
        {
            //select * from ApiResources where Name=@Name and Enabled=1;
            var apiResources = await _db.Queryable<ApiResource>()
                                        .Where(m => m.Enabled && m.Name == name)
                                        .ToListAsync();

            /*select * from ApiResources t1 
             * inner join ApiScopes t2 on t1.Id = t2.ApiResourceId 
             * where t1.Name = @name and Enabled = 1
            */
            var apiScopes = await _db.Queryable<ApiResourceScope>().InnerJoin<ApiResource>((a, b) => a.ApiResourceId == b.Id)
                                        .Where((a, b) => b.Enabled && b.Name == name)
                                        .ToListAsync();


            var apiresource = apiResources[0];
            apiresource.Scopes = apiScopes;
            var model = new IdentityServer4.Models.ApiResource()
            {
                Name = apiresource.Name,
                Enabled = apiresource.Enabled
            };

            return model;
        }

        public async Task<IEnumerable<IdentityServer4.Models.ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames)
        {
            var list = await _db.Queryable<ApiResource>()
                                .Where(x => apiResourceNames.Contains(x.Name) && x.Enabled)
                                .Select<IdentityServer4.Models.ApiResource>()
                                .ToListAsync();
            return list;
        }

        /// <summary>
        /// 根据作用域信息获取接口资源
        /// </summary>
        /// <param name="scopeNames"></param>
        /// <returns></returns>
        public async Task<IEnumerable<IdentityServer4.Models.ApiResource>> FindApiResourcesByScopeAsync(IEnumerable<string> scopeNames)
        {
            if (!scopeNames.Any())
            {
                return null;
            }

            var apiResourceData = new List<IdentityServer4.Models.ApiResource>();

            string _scopes = "";
            foreach (var scope in scopeNames)
            {
                _scopes += "'" + scope + "',";
            }
            _scopes = _scopes.Substring(0, _scopes.Length - 1);

            /*select distinct t1.* from ApiResources t1 
             * inner join ApiScopes t2 on t1.Id=t2.ApiResourceId 
             * where t2.Name in(" + _scopes + ") and Enabled=1
             */
            var apiResource = await _db.Queryable<ApiResource>()
                                       .InnerJoin<ApiScope>((a, b) => a.Id == b.Id)
                                       .Where((a, b) => a.Enabled && b.Name.Contains(_scopes))
                                       .Distinct()
                                       .ToListAsync();

            foreach (var apimodel in apiResource)
            {

                /*"select * from ApiScopes where ApiResourceId=@id";*/
                apimodel.Scopes = await _db.Queryable<ApiResourceScope>()
                                        .Where(m => m.ApiResourceId == apimodel.Id)
                                        .ToListAsync();

                apiResourceData.Add(apimodel.ToModel());
            }

            return apiResourceData;
        }

        public async Task<IEnumerable<IdentityServer4.Models.ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
        {
            var list = await _db.Queryable<ApiResource, ApiScope>((x, o) => x.Name == o.Name)
                                .Where((x, o) => scopeNames.Contains(o.Name) && x.Enabled)
                                .Select<ApiResource>()
                                .ToListAsync(m=>m.ToModel());
            return list;
        }

        public async Task<IEnumerable<IdentityServer4.Models.ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)
        {
            var list = await _db.Queryable<ApiScope>()
                                .Where(x => scopeNames.Contains(x.Name))
                                .Select<ApiScope>()
                                .ToListAsync(m => m.ToModel());
            return list;
        }

   

        /// <summary>
        /// 根据scope获取身份资源
        /// </summary>
        /// <param name="scopeNames"></param>
        /// <returns></returns>
        public async Task<IEnumerable<IdentityServer4.Models.IdentityResource>> FindIdentityResourcesByScopeAsync(IEnumerable<string> scopeNames)
        {
            if (!scopeNames.Any())
            {
                return null;
            }
            var apiResourceData = new List<IdentityServer4.Models.IdentityResource>();

            string _scopes = "";
            foreach (var scope in scopeNames)
            {
                _scopes += "'" + scope + "',";
            }
            _scopes = _scopes.Substring(0, _scopes.Length - 1);

            //暂不实现 IdentityClaims
            //"select * from IdentityResources where Enabled=1 and Name in(" + _scopes + ")"
            var identityResources = await _db.Queryable<IdentityResource>()
                                      .Where(m => m.Enabled && m.Name.Contains(_scopes))
                                      .ToListAsync();

            foreach (var model in identityResources)
            {
                apiResourceData.Add(model.ToModel());
            }
            return apiResourceData;
        }

        public async Task<IEnumerable<IdentityServer4.Models.IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames)
        {
            var list = await _db.Queryable<IdentityResource>().Where(x => scopeNames.Contains(x.Name) && x.Enabled)
                                .Select<IdentityServer4.Models.IdentityResource>()
                                .ToListAsync();
            return list;
        }

        /// <summary>
        /// 获取所有资源实现
        /// </summary>
        /// <returns></returns>
        public async Task<IdentityServer4.Models.Resources> GetAllResourcesAsync()
        {
            var identityResourceData = await _db.Queryable<IdentityResource>()
                                                .Where(x => x.Enabled)
                                                .Select<IdentityServer4.Models.IdentityResource>()
                                                .ToListAsync();

            var apiResourceData = await _db.Queryable<ApiResource>()
                                           .Where(x => x.Enabled)
                                           .Select<IdentityServer4.Models.ApiResource>()
                                           .ToListAsync();

            var apiScopeData = await _db.Queryable<ApiScope>()
                                        .Select<IdentityServer4.Models.ApiScope>()
                                        .ToListAsync();

            var model = new IdentityServer4.Models.Resources(identityResourceData, apiResourceData, apiScopeData);
            return model;
        } 
    }
}
